package com.mybatis.boost.extend.session;

import com.mybatis.boost.extend.exception.MyBatisExceptionTranslator;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration;
import org.mybatis.spring.boot.autoconfigure.MybatisProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.dao.support.PersistenceExceptionTranslator;

import javax.sql.DataSource;

/**
 * @author jearton
 * @since 2017/2/13
 */
@Configuration
@ConditionalOnClass({SqlSessionFactory.class, SqlSessionFactoryBean.class})
@ConditionalOnBean({DataSource.class, SqlSessionFactory.class})
@AutoConfigureBefore(MybatisAutoConfiguration.class)
public class SqlSessionAutoConfiguration {

    private final SqlSessionFactory sqlSessionFactory;

    private final MybatisProperties properties;

    @Autowired
    public SqlSessionAutoConfiguration(SqlSessionFactory sqlSessionFactory, MybatisProperties properties) {
        this.sqlSessionFactory = sqlSessionFactory;
        this.properties = properties;
    }

    @Bean
    @ConditionalOnMissingBean
    public org.mybatis.spring.SqlSessionTemplate sqlSessionTemplate() {
        ExecutorType executorType = this.properties.getExecutorType();
        PersistenceExceptionTranslator exceptionTranslator = new MyBatisExceptionTranslator(
                sqlSessionFactory.getConfiguration().getEnvironment().getDataSource(), true);
        if (executorType != null) {
            return new SqlSessionTemplate(sqlSessionFactory, executorType, exceptionTranslator);
        } else {
            return new SqlSessionTemplate(sqlSessionFactory, exceptionTranslator);
        }
    }
}
